﻿#region Using Directives

    using System;
    using System.Reflection;
    using System.Text;

#endregion

namespace MarketPulse.BusinessLogic.Private.StateMachine
{
    [Serializable]
    internal class AssignmentStateContext : IAssignmentStateContext
    {
        #region Member Variables

            /// <summary>Property that stores the name of the class.</summary>
            private static readonly Type mClass = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;

            private IAssignmentState mState;

            private Assignment mAssignment;

            protected bool mThrowIfInvalid;

        #endregion

        #region Methods

            internal AssignmentStateContext(Guid initialAssignmentStateGUID, Assignment assignment, bool throwIfInvalid)
            {
                mState = AssignmentStateFactory.Create(initialAssignmentStateGUID, throwIfInvalid);
                mAssignment = assignment;
                mThrowIfInvalid = throwIfInvalid;
            }

            public void SetState(IAssignmentState assignmentState)
            {
                mState = assignmentState;
                mAssignment.AssignmentStatusTypeGuid = mState.StateGuid;
            }

            public IAssignmentState GetState()
            {
                return mState;
            }

            public bool CanTransition(string eventName)
            {
                MethodInfo methodInfo = mClass.GetMethod(eventName);

                if (methodInfo == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.Append("Unknown event: [ ");
                    sb.Append(eventName);
                    sb.Append(" ] !");
                    throw new ArgumentException(sb.ToString());
                }

                ParameterInfo[] paramInfo = methodInfo.GetParameters();
                object[] args = new object[paramInfo.Length];
                args[0] = true;
                for (ushort i = 1; i < paramInfo.Length; ++i)
                {
                    args[i] = null;
                }

                return (bool)mClass.InvokeMember(eventName,
                                                    BindingFlags.Public
                                                    | BindingFlags.InvokeMethod
                                                    | BindingFlags.IgnoreCase
                                                    | BindingFlags.Instance,
                                                    null, this, args);
            }

            public bool Assign(bool tryTransition, Guid userGuid, DateTime plannedDateTime)
            {
                return mState.Assign(this, tryTransition, userGuid, plannedDateTime);
            }

            //public bool Unassign(bool tryTransition, Assignment.PaymentStatus payment)
            //{
            //    return mState.Unassign(this, tryTransition, payment);
            //}

            public bool Release(bool tryTransition)
            {
                return mState.Release(this, tryTransition);
            }

            public bool StartDataEntry(bool tryTransition)
            {
                return mState.StartDataEntry(this, tryTransition);
            }

            public bool DataEnter(bool tryTransition, System.Xml.Linq.XElement responses)
            {
                return mState.DataEnter(this, tryTransition, responses);
            }

            public bool CompleteDataEntry(bool tryTransition)
            {
                return mState.CompleteDataEntry(this, tryTransition);
            }

            public bool QAStartDataEntry(bool tryTransition)
            {
                return mState.QAStartDataEntry(this, tryTransition);
            }

            public bool QADataEnter(bool tryTransition)
            {
                return mState.QADataEnter(this, tryTransition);
            }

            public bool QAApprove(bool tryTransition)
            {
                return mState.QAApprove(this, tryTransition);
            }

            public bool QAFail(bool tryTransition)
            {
                return mState.QAFail(this, tryTransition);
            }

            public bool QAPutOnHold(bool tryTransition)
            {
                return mState.QAPutOnHold(this, tryTransition);
            }

            public bool QAReopen(bool tryTransition)
            {
                return mState.QAReopen(this, tryTransition);
            }

            public bool MarkReadyForTransfer(bool tryTransition)
            {
                return mState.MarkReadyForTransfer(this, tryTransition);
            }

            public bool Revisit(bool tryTransition)
            {
                return mState.Revisit(this, tryTransition);
            }

        #endregion

    }
}
